home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Newswatcher 2.0b22 / NW Source / Source / collapse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-29  |  8.9 KB  |  307 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     collapse.c
  4.  
  5.     This module handles collapsing and expanding threads.
  6.     
  7.     Copyright © 1994, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include "glob.h"
  12. #include "collapse.h"
  13. #include "menus.h"
  14. #include "newswatcher.h"
  15. #include "windutil.h"
  16. #include "dialog.h"
  17. #include "listutil.h"
  18.  
  19.  
  20.  
  21.  
  22. /*----------------------------------------------------------------------------
  23.     ExpandCollapseThread 
  24.     
  25.     Expand or collapse a single thread.
  26.             
  27.     Entry:    wind = pointer to subject window.
  28.             theCell = any cell in the thread to be expanded or collapsed.
  29.             
  30.     Exit:    function result = true if thead collapsed, false if expanded.
  31. ----------------------------------------------------------------------------*/
  32.  
  33. Boolean ExpandCollapseThread (WindowPtr wind, Cell theCell)
  34. {
  35.     TWindow **info;
  36.     ListHandle theList;
  37.     TSubject **subjectArray, theSubject;
  38.     Cell tmpCell, newCell;
  39.     long finalTicks;
  40.     short i, nextInThread, cellDataLen, index;
  41.     Rect inval;
  42.     short visTopBeforeDelRow, visTopAfterDelRow;
  43.     
  44.     info = (TWindow**)GetWRefCon(wind);
  45.     theList = (**info).theList;
  46.     subjectArray = (**info).subjectArray;
  47.     cellDataLen = 2;
  48.     LGetCell(&index, &cellDataLen, theCell, theList);
  49.     theSubject = (*subjectArray)[index];
  50.     if (theSubject.threadOrdinal != 1) {
  51.         theCell.v -= theSubject.threadOrdinal-1;
  52.         LGetCell(&index, &cellDataLen, theCell, theList);
  53.         theSubject = (*subjectArray)[index];
  54.     }
  55.     theSubject.collapsed = !theSubject.collapsed;
  56.     nextInThread = index;
  57.     for (i = 0; i < theSubject.threadLength; i++) {
  58.         (*subjectArray)[nextInThread].collapsed = theSubject.collapsed;
  59.         nextInThread = (*subjectArray)[nextInThread].nextInThread;
  60.     }
  61.     (*subjectArray)[index].onlyRedrawTriangle = true;
  62.     (*subjectArray)[index].onlyRedrawCheck = false;
  63.     (*subjectArray)[index].drawTriangleFilled = true;
  64.     LDraw(theCell, theList);
  65.     (*subjectArray)[index].onlyRedrawTriangle = false;
  66.     (*subjectArray)[index].onlyRedrawCheck = true;
  67.     LDraw(theCell, theList);
  68.     (*subjectArray)[index].onlyRedrawTriangle = true;
  69.     (*subjectArray)[index].onlyRedrawCheck = false;
  70.     
  71.     if (theSubject.collapsed) {
  72.         visTopBeforeDelRow = (**theList).visible.top;
  73.         LDelRow(theSubject.threadLength-1, theCell.v+1, theList);
  74.         visTopAfterDelRow = (**theList).visible.top;
  75.         if (visTopBeforeDelRow != visTopAfterDelRow)
  76.             (*subjectArray)[index].onlyRedrawTriangle = false;
  77.         SetPt(&tmpCell, 0, 0);
  78.         if (!LGetSelect(true, &tmpCell, theList)) 
  79.             MyLSetSelect(true, theCell, theList);
  80.     } else {
  81.         LSetDrawingMode(false, theList);
  82.         LAddRow(theSubject.threadLength-1, theCell.v+1, theList);
  83.         newCell = theCell;
  84.         nextInThread = theSubject.nextInThread;
  85.         for (i = 1; i < theSubject.threadLength; i++) {
  86.             newCell.v++;
  87.             LSetCell(&nextInThread, 2, newCell, theList);
  88.             nextInThread = (*subjectArray)[nextInThread].nextInThread;
  89.         }
  90.         LSetDrawingMode(true, theList);
  91.         inval = wind->portRect;
  92.         inval.top = (**info).panelHeight + (theCell.v - (**theList).visible.top + 1) *
  93.             (**theList).cellSize.v;
  94.         inval.right -= 15;
  95.         inval.bottom -= 15;
  96.         InvalRect(&inval);
  97.     }
  98.     
  99.     Delay(8, &finalTicks);
  100.     (*subjectArray)[index].drawTriangleFilled = false;
  101.     LDraw(theCell, theList);
  102.     (*subjectArray)[index].onlyRedrawTriangle = false;
  103.     return theSubject.collapsed;
  104. }
  105.  
  106.  
  107.  
  108. /*----------------------------------------------------------------------------
  109.     RezoomSubjectWindow 
  110.     
  111.     Rezoom a subject window after a thread has been expanded if the
  112.     "Zoom windows" preference is turned on and the window is
  113.     not locked.
  114.             
  115.     Entry:    wind = pointer to subject window.
  116.             expanded = true if thread expanded, false if contracted.
  117.             
  118.     Exit:    function result = error code.
  119. ----------------------------------------------------------------------------*/
  120.     
  121. OSErr RezoomSubjectWindow (WindowPtr wind, Boolean expanded)
  122. {
  123.     TWindow **info;
  124.     ListHandle theList;
  125.     ControlHandle scrollBar;
  126.     OSErr err = noErr;
  127.     
  128.     info = (TWindow**)GetWRefCon(wind);
  129.     theList = (**info).theList;
  130.     scrollBar = (**theList).vScroll;
  131.     if (expanded && gPrefs.reZoomWindows && 
  132.         GetControlMaximum(scrollBar) > 0 && !(**info).windPosLocked) 
  133.     {
  134.         err = DoZoom(wind, inZoomOut);
  135.         if (err != noErr) return err;
  136.     } else {
  137.         SetWindowNeedsZooming(wind);
  138.     }
  139.     return noErr;
  140. }
  141.  
  142.  
  143.  
  144. /*----------------------------------------------------------------------------
  145.     DoExpandCollapseSelectedThread 
  146.     
  147.     Expand or collapse just the currently selected thread.
  148.             
  149.     Entry:    wind = pointer to subject window.
  150.     
  151.     Exit:    function result = error code.
  152. ----------------------------------------------------------------------------*/
  153.     
  154. OSErr DoExpandCollapseSelectedThread (WindowPtr wind)
  155. {
  156.     TWindow **info;
  157.     ListHandle theList;
  158.     TSubject **subjectArray;
  159.     Cell theCell, tmpCell;
  160.     short cellDataLen, index;
  161.     TSubject theSubject;
  162.     Boolean collapsed;
  163.     OSErr err = noErr;
  164.  
  165.     info = (TWindow**)GetWRefCon(wind);
  166.     theList = (**info).theList;
  167.     subjectArray = (**info).subjectArray;
  168.     SetPt(&theCell, 0, 0);
  169.     if (!LGetSelect(true, &theCell, theList)) return noErr;
  170.     tmpCell = theCell;
  171.     tmpCell.v++;
  172.     if (LGetSelect(true, &tmpCell, theList)) return noErr;
  173.     cellDataLen = 2;
  174.     LGetCell(&index, &cellDataLen, theCell, theList);
  175.     theSubject = (*subjectArray)[index];
  176.     if (theSubject.threadLength <= 1) return noErr;
  177.     collapsed = ExpandCollapseThread(wind, theCell);
  178.     err = RezoomSubjectWindow(wind, !collapsed);
  179.     if (err != noErr) return err;
  180.     return noErr;
  181. }
  182.  
  183.  
  184.  
  185. /*----------------------------------------------------------------------------
  186.     TriangleClick 
  187.     
  188.     Handle a click on a triangle thread control.
  189.             
  190.     Entry:    wind = pointer to subject window.
  191.             where = location of mouse down in local coordinates.
  192.             
  193.     Exit:    function result = error code.
  194.             *triangleClicked = true if triangle control clicked.
  195. ----------------------------------------------------------------------------*/
  196.  
  197. OSErr TriangleClick (WindowPtr wind, Point where, Boolean *triangleClicked)
  198. {
  199.     TWindow **info;
  200.     ListHandle theList;
  201.     TSubject **subjectArray, theSubject;
  202.     FontInfo fontInfo;
  203.     Cell theCell;
  204.     short index, cellDataLen;
  205.     Rect hitRect;
  206.     Boolean inHitRect, newInHitRect;
  207.     short visTop, cellHeight;
  208.     Boolean collapsed;
  209.     short panelHeight;
  210.     OSErr err = noErr;
  211.  
  212.     *triangleClicked = false;
  213.     info = (TWindow**)GetWRefCon(wind);
  214.     panelHeight = (**info).panelHeight;
  215.     theList = (**info).theList;
  216.     visTop = (**theList).visible.top;
  217.     cellHeight = (**theList).cellSize.v;
  218.     subjectArray = (**info).subjectArray;
  219.     GetFontInfo(&fontInfo);
  220.     SetRect(&hitRect, 0, 0, (**theList).indent.h + fontInfo.ascent, 0);
  221.     if (where.h > hitRect.right) return noErr;
  222.     if (!PtInListCell(where, theList)) return noErr;
  223.     theCell.h = 0;
  224.     theCell.v = (where.v - panelHeight)/cellHeight + visTop;
  225.     cellDataLen = 2;
  226.     LGetCell(&index, &cellDataLen, theCell, theList);
  227.     theSubject = (*subjectArray)[index];
  228.     if (theSubject.threadLength == 1 || theSubject.threadOrdinal > 1) 
  229.         return noErr;
  230.     (*subjectArray)[index].drawTriangleFilled = inHitRect =  true;
  231.     (*subjectArray)[index].onlyRedrawTriangle = true;
  232.     LDraw(theCell, theList);
  233.     hitRect.top = (theCell.v - visTop) * cellHeight + panelHeight;
  234.     hitRect.bottom = hitRect.top + cellHeight;
  235.     while (StillDown()) {
  236.         GetMouse(&where);
  237.         newInHitRect = PtInRect(where, &hitRect);
  238.         if (newInHitRect != inHitRect) {
  239.             (*subjectArray)[index].drawTriangleFilled = newInHitRect;
  240.             LDraw(theCell, theList);
  241.             inHitRect = newInHitRect;
  242.         }
  243.     }
  244.     if (!inHitRect) {
  245.         (*subjectArray)[index].drawTriangleFilled = false;
  246.         (*subjectArray)[index].onlyRedrawTriangle = false;
  247.         return noErr;
  248.     }
  249.     collapsed = ExpandCollapseThread(wind, theCell);
  250.     err = RezoomSubjectWindow(wind, !collapsed);
  251.     if (err != noErr) return err;
  252.     *triangleClicked = true;
  253.     return noErr;
  254. }
  255.  
  256.  
  257.  
  258. /*----------------------------------------------------------------------------
  259.     ExpandCollapseKey 
  260.     
  261.     Handle the Command-arrow key shortcuts for exanding and collapsing threads.
  262.             
  263.     Entry:    wind = pointer to subject window.
  264.             theChar = the character (left or right arrow).
  265.             
  266.     Exit:    function result = error code.
  267. ----------------------------------------------------------------------------*/
  268.  
  269. OSErr ExpandCollapseKey (WindowPtr wind, char theChar)
  270. {
  271.     TWindow **info;
  272.     ListHandle theList;
  273.     TSubject **subjectArray;
  274.     Cell theCell;
  275.     short cellDataLen, index;
  276.     TSubject theSubject;
  277.     Boolean expanded = false;
  278.     Boolean changed = false;
  279.     OSErr err = noErr;
  280.  
  281.     info = (TWindow**)GetWRefCon(wind);
  282.     theList = (**info).theList;
  283.     subjectArray = (**info).subjectArray;
  284.  
  285.     SetPt(&theCell, 0, 0);
  286.     while (true) {
  287.         if (!LGetSelect(true, &theCell, theList)) break;
  288.         cellDataLen = 2;
  289.         LGetCell(&index, &cellDataLen, theCell, theList);
  290.         theSubject = (*subjectArray)[index];
  291.         if (theSubject.threadLength > 1)
  292.             if (theSubject.collapsed && theChar == rightArrow ||
  293.                 !theSubject.collapsed && theChar == leftArrow) 
  294.             { 
  295.                 ExpandCollapseThread(wind, theCell);
  296.                 changed = true;
  297.                 if (theChar == rightArrow) expanded = true;
  298.             }
  299.         theCell.v++;
  300.     }
  301.     if (changed) {
  302.         err = RezoomSubjectWindow(wind, expanded);
  303.         if (err != noErr) return err;
  304.     }
  305.     return noErr;
  306. }
  307.